/**
 * 节流模式: 图片触底加载、鼠标滚动加载、锚点数据的汇总上传
 * */

// 防抖函数： 固定频率执行函数,一定时间段内最后一次触发为准
function antiShake(callBack, isClear=false, delay=500,){
    if(callBack&&callBack instanceof Function&&!isClear){
        antiShake(callBack,true) // 重置定时器

        callBack.timer = setTimeout(()=>{
            callBack.call({}, Array.prototype.slice.call(arguments,3))
            antiShake(callBack,true)
        },delay)
    }else if(isClear&&callBack&&callBack instanceof Function){
        clearTimeout(callBack.timer||null);
        callBack.timer = null
    }
}

function testShake(i){
    console.log('test shake: ', i);
}
for(let i=0;i<10;i++){
    antiShake( testShake,false, 50, i)
}

setTimeout(()=>{
    antiShake(testShake,false, 50, 100)
},60)

const shakeFunc = toAntiShakeFunc(testShake,50)
for(let i=20;i<30;i++){
    shakeFunc(i)
}

setTimeout(()=>{
    shakeFunc(200)
},60)

// 将一个函数变为防抖函数并返回之
function toAntiShakeFunc(fn,delay=300){
    if(fn&&fn instanceof Function){
        let timer = null, that = this
        return function(){
            if(timer){
                clearTimeout(timer)
            }
            timer = setTimeout(()=>{ 
                fn.call(that, Array.prototype.slice.call(arguments,0))
                clearTimeout(timer)
            },delay)
        }
    }
}


// 将函数节流执行: 固定频率执行函数,一定时间段内第一次触发为准
function throttle(callback, isClear=false, delay=300){
    if(!isClear&&callback&&callback instanceof Function){

        if(!callback.timer){
            callback.timer = setTimeout(()=>{
                callback.call(this,Array.prototype.slice.call(arguments,3))
                throttle(callback,true)
            })
        }
    }else if(isClear&&callback&&callback instanceof Function){
        clearTimeout(callback.timer||null)
        callback.timer = null
    }
}


function testThrottle(i){
    console.log('test throttle: ', i);
}
for(let i=0;i<10;i++){
    throttle( testThrottle,false, 50, i)
}

setTimeout(()=>{
    throttle(testThrottle,false, 50, 100)
},60)


// 将一个函数变为节流函数并返回之
function toAntiThrottleFunc(fn,delay=300){
    if(fn&&fn instanceof Function){
        let timer = null, that = this
        return function(){
            if(timer){
                return
            }
            timer = setTimeout(()=>{ 
                fn.call(that, Array.prototype.slice.call(arguments,0))
                clearTimeout(timer)
                timer = null
            },delay)
        }
    }
}

const throttleFunc = toAntiThrottleFunc(testThrottle,50)
for(let i=30;i<40;i++){
    throttleFunc(i)
}

setTimeout(()=>{
    throttleFunc(300)
},160)

